From f69ab07dabd04fb419d9441347f776aa075f6040 Mon Sep 17 00:00:00 2001 From: "djm@kirby.fc.hp.com" Date: Mon, 9 May 2005 23:30:20 +0000 Subject: [PATCH] bitkeeper revision 1.1389.9.4 (427ff28cpHTPvFmKde6BQbpMm2W-Qw) Add itc hyperprivop code and hyperprivop counters --- xen/arch/ia64/privop.c | 103 ++++++++++++++++++++++++++---------- xen/arch/ia64/process.c | 2 +- xen/arch/ia64/vcpu.c | 14 +++++ xen/include/asm-ia64/vcpu.h | 2 + 4 files changed, 92 insertions(+), 29 deletions(-) diff --git a/xen/arch/ia64/privop.c b/xen/arch/ia64/privop.c index c17adc5bde..f617d2d0b4 100644 --- a/xen/arch/ia64/privop.c +++ b/xen/arch/ia64/privop.c @@ -205,7 +205,8 @@ IA64FAULT priv_itc_d(VCPU *vcpu, INST64 inst) return(IA64_ILLOP_FAULT); if ((fault = vcpu_get_ifa(vcpu,&ifa)) != IA64_NO_FAULT) return(IA64_ILLOP_FAULT); - pte = vcpu_get_gr(vcpu,inst.M41.r2); + if (!inst.inst) pte = vcpu_get_tmp(vcpu,0); + else pte = vcpu_get_gr(vcpu,inst.M41.r2); return (vcpu_itc_d(vcpu,pte,itir,ifa)); } @@ -219,7 +220,8 @@ IA64FAULT priv_itc_i(VCPU *vcpu, INST64 inst) return(IA64_ILLOP_FAULT); if ((fault = vcpu_get_ifa(vcpu,&ifa)) != IA64_NO_FAULT) return(IA64_ILLOP_FAULT); - pte = vcpu_get_gr(vcpu,inst.M41.r2); + if (!inst.inst) pte = vcpu_get_tmp(vcpu,0); + else pte = vcpu_get_gr(vcpu,inst.M41.r2); return (vcpu_itc_i(vcpu,pte,itir,ifa)); } @@ -695,7 +697,7 @@ priv_handle_op(VCPU *vcpu, REGS *regs, int privlvl) //printf("We who are about do die salute you\n"); printf("handle_op: can't handle privop at 0x%lx (op=0x%016lx) slot %d (type=%d)\n", iip, (UINT64)inst.inst, slot, slot_type); - //printf("vtop(0x%lx)==0x%lx\r\n", iip, tr_vtop(iip)); + //printf("vtop(0x%lx)==0x%lx\n", iip, tr_vtop(iip)); //thread_mozambique("privop fault\n"); return (IA64_ILLOP_FAULT); } @@ -759,19 +761,37 @@ priv_emulate(VCPU *vcpu, REGS *regs, UINT64 isr) // FIXME: Move these to include/public/arch-ia64? -#define HYPERPRIVOP_RFI 1 -#define HYPERPRIVOP_RSM_DT 2 -#define HYPERPRIVOP_SSM_DT 3 -#define HYPERPRIVOP_COVER 4 +#define HYPERPRIVOP_RFI 0x1 +#define HYPERPRIVOP_RSM_DT 0x2 +#define HYPERPRIVOP_SSM_DT 0x3 +#define HYPERPRIVOP_COVER 0x4 +#define HYPERPRIVOP_ITC_D 0x5 +#define HYPERPRIVOP_ITC_I 0x6 +#define HYPERPRIVOP_MAX 0x6 + +char *hyperpriv_str[HYPERPRIVOP_MAX+1] = { + 0, "rfi", "rsm.dt", "ssm.dt", "cover", "itc.d", "itc.i", + 0 +}; + +unsigned long hyperpriv_cnt[HYPERPRIVOP_MAX+1] = { 0 }; /* hyperprivops are generally executed in assembly (with physical psr.ic off) * so this code is primarily used for debugging them */ int -ia64_hyperprivop(unsigned long iim) +ia64_hyperprivop(unsigned long iim, REGS *regs) { struct exec_domain *ed = (struct domain *) current; + INST64 inst; + UINT64 val; // FIXME: Add instrumentation for these +// FIXME: Handle faults appropriately for these + if (!iim || iim > HYPERPRIVOP_MAX) { + printf("bad hyperprivop; ignored\n"); + return 1; + } + hyperpriv_cnt[iim]++; switch(iim) { case HYPERPRIVOP_RFI: (void)vcpu_rfi(ed); @@ -785,6 +805,14 @@ ia64_hyperprivop(unsigned long iim) case HYPERPRIVOP_COVER: (void)vcpu_cover(ed); return 1; + case HYPERPRIVOP_ITC_D: + inst.inst = 0; + (void)priv_itc_d(ed,inst); + return 1; + case HYPERPRIVOP_ITC_I: + inst.inst = 0; + (void)priv_itc_i(ed,inst); + return 1; } return 0; } @@ -843,61 +871,61 @@ int dump_privop_counts(char *buf) sum += privcnt.rfi; sum += privcnt.bsw0; sum += privcnt.bsw1; sum += privcnt.cover; for (i=0; i < 64; i++) sum += privcnt.Mpriv_cnt[i]; - s += sprintf(s,"Privop statistics: (Total privops: %ld)\r\n",sum); + s += sprintf(s,"Privop statistics: (Total privops: %ld)\n",sum); if (privcnt.mov_to_ar_imm) - s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.mov_to_ar_imm, + s += sprintf(s,"%10d %s [%d%%]\n", privcnt.mov_to_ar_imm, "mov_to_ar_imm", (privcnt.mov_to_ar_imm*100L)/sum); if (privcnt.mov_to_ar_reg) - s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.mov_to_ar_reg, + s += sprintf(s,"%10d %s [%d%%]\n", privcnt.mov_to_ar_reg, "mov_to_ar_reg", (privcnt.mov_to_ar_reg*100L)/sum); if (privcnt.mov_from_ar) - s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.mov_from_ar, + s += sprintf(s,"%10d %s [%d%%]\n", privcnt.mov_from_ar, "privified-mov_from_ar", (privcnt.mov_from_ar*100L)/sum); if (privcnt.ssm) - s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.ssm, + s += sprintf(s,"%10d %s [%d%%]\n", privcnt.ssm, "ssm", (privcnt.ssm*100L)/sum); if (privcnt.rsm) - s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.rsm, + s += sprintf(s,"%10d %s [%d%%]\n", privcnt.rsm, "rsm", (privcnt.rsm*100L)/sum); if (privcnt.rfi) - s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.rfi, + s += sprintf(s,"%10d %s [%d%%]\n", privcnt.rfi, "rfi", (privcnt.rfi*100L)/sum); if (privcnt.bsw0) - s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.bsw0, + s += sprintf(s,"%10d %s [%d%%]\n", privcnt.bsw0, "bsw0", (privcnt.bsw0*100L)/sum); if (privcnt.bsw1) - s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.bsw1, + s += sprintf(s,"%10d %s [%d%%]\n", privcnt.bsw1, "bsw1", (privcnt.bsw1*100L)/sum); if (privcnt.cover) - s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.cover, + s += sprintf(s,"%10d %s [%d%%]\n", privcnt.cover, "cover", (privcnt.cover*100L)/sum); if (privcnt.fc) - s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.fc, + s += sprintf(s,"%10d %s [%d%%]\n", privcnt.fc, "privified-fc", (privcnt.fc*100L)/sum); if (privcnt.cpuid) - s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.cpuid, + s += sprintf(s,"%10d %s [%d%%]\n", privcnt.cpuid, "privified-getcpuid", (privcnt.cpuid*100L)/sum); for (i=0; i < 64; i++) if (privcnt.Mpriv_cnt[i]) { - if (!Mpriv_str[i]) s += sprintf(s,"PRIVSTRING NULL!!\r\n"); - else s += sprintf(s,"%10d %s [%d%%]\r\n", privcnt.Mpriv_cnt[i], + if (!Mpriv_str[i]) s += sprintf(s,"PRIVSTRING NULL!!\n"); + else s += sprintf(s,"%10d %s [%d%%]\n", privcnt.Mpriv_cnt[i], Mpriv_str[i], (privcnt.Mpriv_cnt[i]*100L)/sum); if (i == 0x24) { // mov from CR s += sprintf(s," ["); for (j=0; j < 128; j++) if (from_cr_cnt[j]) { if (!cr_str[j]) - s += sprintf(s,"PRIVSTRING NULL!!\r\n"); + s += sprintf(s,"PRIVSTRING NULL!!\n"); s += sprintf(s,"%s(%d),",cr_str[j],from_cr_cnt[j]); } - s += sprintf(s,"]\r\n"); + s += sprintf(s,"]\n"); } else if (i == 0x2c) { // mov to CR s += sprintf(s," ["); for (j=0; j < 128; j++) if (to_cr_cnt[j]) { if (!cr_str[j]) - s += sprintf(s,"PRIVSTRING NULL!!\r\n"); + s += sprintf(s,"PRIVSTRING NULL!!\n"); s += sprintf(s,"%s(%d),",cr_str[j],to_cr_cnt[j]); } - s += sprintf(s,"]\r\n"); + s += sprintf(s,"]\n"); } } return s - buf; @@ -919,7 +947,7 @@ int zero_privop_counts(char *buf) for (i=0; i < 64; i++) privcnt.Mpriv_cnt[i] = 0; for (j=0; j < 128; j++) from_cr_cnt[j] = 0; for (j=0; j < 128; j++) to_cr_cnt[j] = 0; - s += sprintf(s,"All privop statistics zeroed\r\n"); + s += sprintf(s,"All privop statistics zeroed\n"); return s - buf; } @@ -943,7 +971,7 @@ int dump_privop_addrs(char *buf) { int i,j; char *s = buf; - s += sprintf(s,"Privop addresses:\r\n"); + s += sprintf(s,"Privop addresses:\n"); for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) { struct privop_addr_count *v = &privop_addr_counter[i]; s += sprintf(s,"%s:\n",v->instname); @@ -969,12 +997,30 @@ void zero_privop_addrs(void) } #endif +int dump_hyperprivop_counts(char *buf) +{ + int i; + char *s = buf; + s += sprintf(s,"Hyperprivops:\n"); + for (i = 1; i <= HYPERPRIVOP_MAX; i++) + if (hyperpriv_cnt[i]) + s += sprintf("%10d %s\n", + hyperpriv_cnt[i], hyperpriv_str[i]); +} + +void zero_hyperprivop_counts(void) +{ + int i; + for (i = 0; i <= HYPERPRIVOP_MAX; i++) hyperpriv_cnt[i] = 0; +} + #define TMPBUFLEN 8*1024 int dump_privop_counts_to_user(char __user *ubuf, int len) { char buf[TMPBUFLEN]; int n = dump_privop_counts(buf); + n += dump_hyperprivop_counts(buf + n); #ifdef PRIVOP_ADDR_COUNT n += dump_privop_addrs(buf + n); #endif @@ -988,6 +1034,7 @@ int zero_privop_counts_to_user(char __user *ubuf, int len) char buf[TMPBUFLEN]; int n = zero_privop_counts(buf); + zero_hyperprivop_counts(); #ifdef PRIVOP_ADDR_COUNT zero_privop_addrs(); #endif diff --git a/xen/arch/ia64/process.c b/xen/arch/ia64/process.c index 985ba7cbed..1e0c10f53f 100644 --- a/xen/arch/ia64/process.c +++ b/xen/arch/ia64/process.c @@ -724,7 +724,7 @@ ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, u vcpu_increment_iip(current); } else if (!PSCB(ed,interrupt_collection_enabled)) { - if (ia64_hyperprivop(iim)) + if (ia64_hyperprivop(iim,regs)) vcpu_increment_iip(current); } else reflect_interruption(ifa,isr,iim,regs,IA64_BREAK_VECTOR); diff --git a/xen/arch/ia64/vcpu.c b/xen/arch/ia64/vcpu.c index c46e7c48d8..29b20a4df0 100644 --- a/xen/arch/ia64/vcpu.c +++ b/xen/arch/ia64/vcpu.c @@ -848,6 +848,20 @@ IA64FAULT vcpu_set_cmcv(VCPU *vcpu, UINT64 val) return (IA64_NO_FAULT); } +/************************************************************************** + VCPU temporary register access routines +**************************************************************************/ +UINT64 vcpu_get_tmp(VCPU *vcpu, UINT64 index) +{ + if (index > 7) return 0; + return PSCB(vcpu,tmp[index]); +} + +void vcpu_set_tmp(VCPU *vcpu, UINT64 index, UINT64 val) +{ + if (index <= 7) PSCB(vcpu,tmp[index]) = val; +} + /************************************************************************** Interval timer routines **************************************************************************/ diff --git a/xen/include/asm-ia64/vcpu.h b/xen/include/asm-ia64/vcpu.h index e3bcfbde79..bb24bad2b2 100644 --- a/xen/include/asm-ia64/vcpu.h +++ b/xen/include/asm-ia64/vcpu.h @@ -147,6 +147,8 @@ extern void vcpu_set_next_timer(VCPU *vcpu); extern BOOLEAN vcpu_timer_expired(VCPU *vcpu); extern UINT64 vcpu_deliverable_interrupts(VCPU *vcpu); extern void vcpu_itc_no_srlz(VCPU *vcpu, UINT64, UINT64, UINT64, UINT64, UINT64); +extern UINT64 vcpu_get_tmp(VCPU *, UINT64); +extern void vcpu_set_tmp(VCPU *, UINT64, UINT64); #endif -- 2.30.2